home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / bin / foomatic-ppd-to-xml < prev    next >
Text File  |  2009-09-18  |  9KB  |  248 lines

  1. #!/usr/bin/perl
  2. # -*- perl -*-
  3.  
  4. # Foomatic printer XML file generator to get XML files corresponding
  5. # to manufacturer-supplied PostScript PPDs (or also PPDs from driver
  6. # packages).
  7.  
  8. use Foomatic::Defaults;
  9. use Foomatic::DB;
  10. use Getopt::Std;
  11. use Data::Dumper;
  12. #use strict;
  13.  
  14. my $debug = 0;
  15.  
  16. # Program name
  17. $0 =~ m!/([^/]+)\s*$!;
  18. my $progname = ($1 || $0);
  19.  
  20. help() if !@ARGV;
  21. #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w);
  22. getopts("d:r:p:lb:f:nh");
  23. help() if $opt_h;
  24. my $drivers = $opt_d;
  25. my $rdriver = $opt_r;
  26. my $pdls = $opt_p;
  27. my $ppdlink = $opt_l;
  28. my $basedir = $opt_b;
  29. my $destdir = $opt_f;
  30. my $nomod = $opt_n;
  31.  
  32. $ppdfile = $ARGV[0];
  33.  
  34. if ($ppdlink && !$drivers) {
  35.     $ppdlink = 0;
  36.     warn("WARNING: \"-l\" set without supplying a driver via \"-d\". No PPD file links will get created!\n");
  37. }
  38.  
  39. my $ppddlpath;
  40. if ($basedir) {
  41.     $basedir =~ s:/+$::;
  42.     if (! -d $basedir) {
  43.     die ("PPD base directory $basedir does not exist!\n");
  44.     }
  45.     if (! -r $ppdfile) {
  46.     $ppddlpath = $ppdfile;
  47.     $ppdfile = $basedir . "/" . $ppdfile;
  48.     if (! -r $ppdfile) {
  49.         die ("Given PPD file not found, neither as $ppddlpath nor as $ppdfile!\n");
  50.     }
  51.     } else {
  52.     $ppdfile =~ m:$basedir/(.*)$:;
  53.     $ppddlpath = $1;
  54.     }
  55. } else {
  56.     if (! -r $ppdfile) {
  57.     die ("Given PPD file $ppdfile not found!\n");
  58.     }
  59.     $ppddlpath = $ppdfile;
  60. }
  61.  
  62. my $parameters = {
  63.     ($drivers ? ('drivers' => [split(',', $drivers)]) : ()),
  64.     ($rdriver ? ('recommendeddriver' => $rdriver) : ()),
  65.     ($pdls ? ('pdls' => [split(',', $pdls)]) : ()),
  66.     ($ppdlink ? ('ppdlink' => 1) : ()),
  67.     ($basedir ? ('basedir' => $basedir) : ()),
  68. };
  69.  
  70. my $db = Foomatic::DB->new();
  71. my $dat = ppdtoperl($ppdfile, $parameters);
  72. my @existing = $db->find_printer("$dat->{'make'}|$dat->{'model'}", 4, 1);
  73. foreach my $product (@{$dat->{ppdproduct}}) {
  74.     my @pids = $db->find_printer("$dat->{'make'}|$product", 4, 1);
  75.     push(@existing,
  76.      grep {
  77.          !Foomatic::DB::member($_, @existing);
  78.      } @pids);
  79. }
  80. push(@existing,
  81.      grep {
  82.      !Foomatic::DB::member($_, @existing);
  83.      } map {
  84.          m:^(.*)\.xml$:; $1;
  85.      } map {
  86.          m:([^/]+)$:; $1;
  87.      } split(/\n/s, 
  88.          `find $libdir/db/source/printer -name "*.xml" -print0 | xargs -0 grep -l $ppddlpath`));
  89. my $entryfound = 0;
  90. foreach my $entry (@existing) {
  91.     my $d = $db->get_printer($entry);
  92.     my $result;
  93.     next if $d->{'noxmlentry'};
  94.     $entryfound = 1;
  95.     last if $nomod;
  96.     $db->{'dat'} = $d;
  97.     if (!defined($parameters->{'drivers'})) {
  98.     $parameters->{'drivers'} = [$dat->{'driver'}];
  99.     }
  100.     if (!defined($parameters->{'pdls'})) {
  101.     $parameters->{'pdls'} = [split(',', $dat->{'general_cmd'})];
  102.     } else {
  103.     push(@{$parameters->{'pdls'}}, split(',', $dat->{'general_cmd'}));
  104.     }
  105.     Foomatic::DB::apply_driver_and_pdl_info($db->{'dat'}, $parameters);
  106.     $db->{'dat'}{'general_ieee'} = $dat->{'general_ieee'} if
  107.     defined($dat->{'general_ieee'}) && 
  108.     !defined($db->{'dat'}{'general_ieee'});
  109.     $db->{'dat'}{'general_mfg'} = $dat->{'general_mfg'} if
  110.     defined($dat->{'general_mfg'}) &&
  111.     !defined($db->{'dat'}{'general_mfg'});
  112.     $db->{'dat'}{'general_mdl'} = $dat->{'general_mdl'} if
  113.     defined($dat->{'general_mdl'}) &&
  114.     !defined($db->{'dat'}{'general_mdl'});
  115.     $db->{'dat'}{'general_des'} = $dat->{'general_des'} if
  116.     defined($dat->{'general_des'}) &&
  117.     !defined($db->{'dat'}{'general_des'});
  118.     $db->{'dat'}{'general_cmd'} = $dat->{'general_cmd'} if
  119.     defined($dat->{'general_cmd'}) &&
  120.     !defined($db->{'dat'}{'general_cmd'});
  121.     $db->{'dat'}{'comment'} .= "\n      <p>\n\n" . $dat->{'comment'};
  122.     my $xml1 = $db->perltoxml('p');
  123.     my $xml2 = $db->get_printer_xml($entry);
  124.     $xml2 =~ s/(<\/functionality>)/$1\n  <driver><\/driver>/s if 
  125.     $xml2 !~ /<driver>/;
  126.     $xml2 = transferregexp($xml1, $xml2,
  127.     '<driver>\S*<\/driver>');
  128.     $xml2 =~ s/(<\/driver>)/$1\n  <drivers>\n  <\/drivers>/s if 
  129.     $xml2 !~ /<drivers>/;
  130.     $xml2 = transferregexp($xml1, $xml2,
  131.     '<drivers>.*<\/drivers>');
  132.     $xml2 =~ s/(<\/(mechanism|url)>)/$1\n  <lang>\n  <\/lang>/s if 
  133.     $xml2 !~ /<lang>/;
  134.     $xml2 = transferregexp($xml1, $xml2,
  135.     '<lang>.*<\/lang>');
  136.     $xml2 =~ s/(<\/lang>)/$1\n  <autodetect>\n  <\/autodetect>/s if 
  137.     $xml2 !~ /<autodetect>/;
  138.     $xml2 =~ s/(<autodetect>)/$1\n    <general>\n    <\/general>/s if 
  139.     $xml2 !~ /<autodetect>[\s\n\r]*<general>/s;
  140.     $xml2 = transferregexp($xml1, $xml2,
  141.     '<autodetect>[\s\n\r]*<general>.*<\/general>');
  142.     $xml2 = transferregexp($xml1, $xml2,
  143.     '<\/drivers>[\s\n\r]*<comments>.*<\/comments>[\s\n\r]*<\/printer>');
  144.     $result = $xml2;
  145.     print "Modifying printer entry $db->{'dat'}{'id'}.xml ...\n";
  146.     open FILE, "> " . ($destdir ? $destdir . "/" : ()) . 
  147.     $db->{'dat'}{'id'} . ".xml" or
  148.     die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
  149.     print FILE $result;
  150.     close FILE;
  151.     delete($db->{'dat'});
  152. }
  153. if (!$entryfound) {
  154.     $db->{'dat'} = $dat;
  155.     $db->{'dat'}{'comment'} =
  156.     "      This database entry was automatically generated\n" .
  157.     "      from the PPD file for this printer.<p>\n\n" .
  158.     $db->{'dat'}{'comment'};
  159.     $db->{'dat'}{'functionality'} = "A";
  160.     foreach my $product (@{$db->{'dat'}{ppdproduct}}) {
  161.     $db->{'dat'}{'model'} =
  162.         Foomatic::DB::clean_manufacturer_name(Foomatic::DB::clean_model_name($product))
  163.         if scalar(@{$db->{'dat'}{ppdproduct}}) > 1;
  164.     $db->{'dat'}{'model'} =~ s/^$db->{'dat'}{'make'}\s*//i;
  165.     $db->{'dat'}{'id'} =
  166.         Foomatic::DB::generatepid($db->{'dat'}{'make'},
  167.                       $db->{'dat'}{'model'});
  168.     if (scalar(@{$db->{'dat'}{ppdproduct}}) > 1) {
  169.         $db->{'dat'}{'general_mfg'} = $db->{'dat'}{'ppdmanufacturer'} if
  170.         $db->{'dat'}{'ppdmanufacturer'} &&
  171.         !$db->{'dat'}{'general_mfg'};
  172.         $db->{'dat'}{'general_mdl'} = $product;
  173.         $db->{'dat'}{'general_ieee'} = "MFG:" .
  174.         $db->{'dat'}{'general_mfg'} .
  175.         ";MDL:" . $db->{'dat'}{'general_mdl'} . ";" .
  176.         ($db->{'dat'}{'general_cmd'} ?
  177.          "CMD:" . $db->{'dat'}{'general_cmd'} . ";" : "");
  178.     }
  179.     $result = $db->perltoxml('p');
  180.     print "Creating new printer entry $db->{'dat'}{'id'}.xml ...\n";
  181.     open FILE, "> " . ($destdir ? $destdir . "/" : ()) . 
  182.         $db->{'dat'}{'id'} . ".xml" or
  183.         die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
  184.     print FILE $result;
  185.     close FILE;
  186.     }
  187.     delete($db->{'dat'});
  188. }
  189.  
  190. exit 0;
  191.  
  192. sub transferregexp {
  193.  
  194.     my ($src, $dest, $regexp) = @_;
  195.  
  196.     # This function copies the text fraction matching $regexp out of
  197.     # the first string, cuts the piece of the second matching $regexp
  198.     # out of the second string and replaces it by the piece copied
  199.     # from the first string. This is mainly for transfering XML
  200.     # sections from one XML file to another (strings can be
  201.     # multi-line) without needing to rewrite the unaffected parts of
  202.     # the XML file.
  203.  
  204.     $src =~ m/($regexp)/s;
  205.     my $totransfer = $1;
  206.     $dest =~ s/$regexp/$totransfer/s if $totransfer;
  207.     return $dest;
  208. }
  209.  
  210. sub help {
  211.     print <<HELP;
  212.  
  213. $progname <options> <ppdfile>
  214. $progname -h
  215.  
  216.  <ppdfile>      : PPD file for which a printer XML file should be created
  217.  -d <drivers>   : Comma-separated list of drivers with which the printer
  218.                   works. First driver is the one for which the PPD file is.
  219.                   If not otherwise stated by the "-r" options, this is also
  220.                   the recommended driver.
  221.  -r <driver>    : Recommended driver. Supply this option to specify another
  222.                   driver than the driver from the PPD/the first one from the
  223.                   "-d" argument as the recommended driver.
  224.  -p <pdls>      : Comma-separated list of known Page Description Languages
  225.                   (PDLs) which the printer supports. This will add all 
  226.                   suitable drivers to the XML entry. Currently supported are:
  227.                   Postscript, PCLXL, PCL6, PCL5e, PCL5c, PCL5, and PCL4.
  228.  -l             : Add a link to the PPD file to the driver entry in the
  229.                   XML file.
  230.  -b <directory> : Base directory for a relative link to the PPD. If the
  231.                   base directory is given, the link set via the -l option 
  232.                   is relative to this directory (and not relative to the
  233.                   current directory). With a base directory given the 
  234.                   <ppdfile> can also be given relative to this directory.
  235.  -f <directory> : Directory where the resulting XML file to write to. The
  236.                   name of the file will be the printer ID with the ".xml"
  237.                   extension.
  238.  -n             : Do not write modified versions of existing XML files,
  239.                   only create XML files for printer for which there is no
  240.                   XML file yet.
  241.  -h             : show help information
  242.  
  243.  
  244. HELP
  245.     exit 1;
  246.  
  247. }
  248.